/*
 * Copyright (C), 2002-2016, 苏宁易购电子商务有限公司
 * FileName: BiStoreRetGdsHomeService.java
 * Author:   13075787
 * Date:     2016年6月18日 下午4:20:45
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.service.impl.bi;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.gson.reflect.TypeToken;
import com.suning.sawp.constants.CacheKeyConstants;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.intf.dao.BiStoreRetGdsDaoService;
import com.suning.sawp.po.bi.BiStoreCateRetGdsMonthBean;
import com.suning.sawp.po.bi.BiStoreRetGdsHomeVo;
import com.suning.sawp.po.bi.BiStoreRetGdsMonthBean;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.RedisCacheUtils;
import com.suning.sawp.service.util.SCMConfigUtil;

/**
 * 统计-退货数据首页<br>
 * 
 * @author 13075787
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service("biStoreRetGdsHomeService")
public class BiStoreRetGdsHomeService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BiStoreRetGdsHomeService.class);

    private static final Integer NUM_ZERO = 0;
    private static final Integer NUM_ONE = 1;
    private static final Integer NUM_THREE = 3;
    private static final Integer NUM_FOUR = 4;
    private static final Integer NUM_SIX = 6;
    private static final Integer NUM_EIGHT = 8;

    @Autowired
    BiStoreRetGdsDaoService biStoreRetGdsDaoService;

    @Resource
    RedisCacheUtils cacheUtils;

    /**
     * 功能描述: <br>
     * 退货首页数据信息展示-常规将数据缓存1小时
     * 
     * @param StoreMan
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public ReturnMsg<Map<String, Object>> queryRetGdsHomeInfo(StoreManDto storeMan) {
        ReturnMsg<Map<String, Object>> result = new ReturnMsg<Map<String, Object>>();
        // data 数据
        Map<String, Object> resultData = new HashMap<String, Object>();
        List<BiStoreRetGdsHomeVo> retList = null;
        if (null != storeMan && StringUtils.isNotBlank(storeMan.getStaffId())) {
            // 兼容店员兼岗位的场景，存在兼任多个店店长的场景，和一个店既是督导又是店长
            String cacheKey = String.format(CacheKeyConstants.STORE_RET_GDS_HOME, storeMan.getStoreCode(), 
                    storeMan.getStaffId(), storeMan.getPositionId());
            // 首先从缓存中拉取数据，缓存不存在则执行下面的方法从数据库中拉取数据
            retList = cacheUtils.get(cacheKey, new TypeToken<List<BiStoreRetGdsHomeVo>>() {
            }.getType());
            if (CollectionUtils.isEmpty(retList)) {
                // 取昨日所在的月份
                Date yestd = DateUtils.getNextDay(new Date(), -1);
                String month = DateUtils.getDateStrByFormat(yestd, DateUtils.YYYYMM_PATTERN);
                // 从数据库中拉取数据
                if (ClerkConstants.STORE_KEEPER.equals(storeMan.getPositionId())) {
                    retList = this.queryRetGdsHomeInfoForKeeper(storeMan.getStoreCode(), month);
                } else if (ClerkConstants.SALE_GUIDE.equals(storeMan.getPositionId())) {
                    retList = this.queryRetGdsHomeInfoForGuide(storeMan.getStoreCode(), storeMan.getCategories(), month);
                } else {
                    LOGGER.info("数据统计-门店退货首页查看，无权限(非店长/非督导)-访问该请求工号：" + storeMan.getStaffId());
                }
                if (CollectionUtils.isNotEmpty(retList)) {
                    // 将该数据添加到缓存中
                    cacheUtils.setex(cacheKey, CacheKeyConstants.STORE_RET_GDS_HOME_EXPIRE_TIME, retList);
                }
            }
        } else {
            result.setError(ErrorCodeConstants.RET_GDS_STATIS_ERR_E004, ErrorCodeConstants.RET_GDS_STATIS_ERR_MAP);
        }
        // 若是督导的话，需要将返回列表中不存在的品类数据补全
        if (ClerkConstants.SALE_GUIDE.equals(storeMan.getPositionId())) {
            if (null == retList) {
                retList = new ArrayList<BiStoreRetGdsHomeVo>();
            }
            retList.addAll(this.wrapperRetListForGuide(retList, storeMan.getCategories()));
        }
        resultData.put("refundInfo", retList);
        // 添加三级利润链接
        resultData.putAll(this.getThreeProfitUrlInfo());
        result.setData(resultData);
        return result;
    }

    /*
     * 对督导的返回结果进行处理，所拥有的品类无返回数据但依然返回品类信息
     */
    private List<BiStoreRetGdsHomeVo> wrapperRetListForGuide(List<BiStoreRetGdsHomeVo> retList,
            List<Category> categories) {
        List<BiStoreRetGdsHomeVo> result = new ArrayList<BiStoreRetGdsHomeVo>();
        Map<String, Object> retMap = new HashMap<String, Object>();
        if (CollectionUtils.isNotEmpty(retList)) {
            for (BiStoreRetGdsHomeVo biStoreRetGdsHomeVo : retList) {
                if (null != biStoreRetGdsHomeVo) {
                    retMap.put(biStoreRetGdsHomeVo.getCategoryCode(), biStoreRetGdsHomeVo);
                }
            }
        }
        // 督导所属的分类不存在retMap中的数据则全部都添加到返回list中
        if (CollectionUtils.isNotEmpty(categories)) {
            for (Category category : categories) {
                if (null == retMap.get(category.getCategoryCode())) {
                    BiStoreRetGdsHomeVo biStoreRetGdsHomeVo = new BiStoreRetGdsHomeVo();
                    biStoreRetGdsHomeVo.setCategoryName(category.getCategoryName());
                    biStoreRetGdsHomeVo.setCategoryCode(category.getCategoryCode());
                    result.add(biStoreRetGdsHomeVo);
                }
            }
        }
        return result;
    }

    /**
     * 退货首页数据信息展示-For 店长
     */
    private List<BiStoreRetGdsHomeVo> queryRetGdsHomeInfoForKeeper(String storeCode, String month) {
        List<BiStoreRetGdsHomeVo> result = null;
        // 获取当月统计量
        BiStoreRetGdsMonthBean storeRetGdsMonth = biStoreRetGdsDaoService.queryCurMonthRetGdsMonth(storeCode, month);
        if (null != storeRetGdsMonth) {
            result = new ArrayList<BiStoreRetGdsHomeVo>();
            BiStoreRetGdsHomeVo biStoreRetGdsHomeVo = new BiStoreRetGdsHomeVo();
            biStoreRetGdsHomeVo.setRank(storeRetGdsMonth.getRank());
            biStoreRetGdsHomeVo.setRefund(storeRetGdsMonth.getRefund());
            biStoreRetGdsHomeVo.setRetGdsNum(storeRetGdsMonth.getRetGdsNum());
            // 退货率-注意小数点后位数
            biStoreRetGdsHomeVo.setRetGdsRate(storeRetGdsMonth.getRetGdsRate());
            // 注意返回给客户端的时间格式
            biStoreRetGdsHomeVo.setStatisDate(this.formatTime(storeRetGdsMonth.getStatisDate()));
            // 同比计算
            biStoreRetGdsHomeVo.setYoy(this.getRetGdsYoyMom(storeRetGdsMonth.getRetGdsRate(),
                    storeRetGdsMonth.getLastYearRetGdsNum(), storeRetGdsMonth.getLastYearSaleVolume()));
            // 环比计算
            biStoreRetGdsHomeVo.setMom(this.getRetGdsYoyMom(storeRetGdsMonth.getRetGdsRate(),
                    storeRetGdsMonth.getLastMonRetGdsNum(), storeRetGdsMonth.getLastMonSaleVolume()));
            result.add(biStoreRetGdsHomeVo);
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 计算同比环比
     */
    private BigDecimal getRetGdsYoyMom(BigDecimal retGdsRate, Integer latRetGdsNum, Integer latVolume) {
        BigDecimal result = null;
        if (null != retGdsRate && null != latRetGdsNum && null != latVolume && latVolume > 0) {
            BigDecimal last = new BigDecimal(Integer.toString(latRetGdsNum)).divide(
                    new BigDecimal(Integer.toString(latVolume)), NUM_SIX, BigDecimal.ROUND_HALF_UP);
            if (null != last && NUM_ONE == last.compareTo(BigDecimal.ZERO)) {
                result = retGdsRate.divide(last, NUM_THREE, BigDecimal.ROUND_HALF_UP).subtract(new BigDecimal(NUM_ONE));
            }
        }
        return result;
    }

    /**
     * 退货首页数据信息展示-For 督导
     */
    private List<BiStoreRetGdsHomeVo> queryRetGdsHomeInfoForGuide(String storeCode, List<Category> categorys, String month) {
        List<BiStoreRetGdsHomeVo> result = null;
        if (CollectionUtils.isNotEmpty(categorys)) {
            // 提取类目编码列表
            List<String> cateCodes = Lists.newArrayList(Lists.transform(categorys, new Function<Category, String>() {
                @Override
                public String apply(Category input) {
                    return input != null ? input.getCategoryCode() : null;
                }
            }));
            List<BiStoreCateRetGdsMonthBean> storeCateRetGdsMonthInfos = biStoreRetGdsDaoService
                    .queryCurMonthCateRetGdsMonth(storeCode, cateCodes, month);
            if (CollectionUtils.isNotEmpty(storeCateRetGdsMonthInfos)) {
                result = Lists.newArrayList(Lists.transform(storeCateRetGdsMonthInfos,
                        new Function<BiStoreCateRetGdsMonthBean, BiStoreRetGdsHomeVo>() {
                            @Override
                            public BiStoreRetGdsHomeVo apply(BiStoreCateRetGdsMonthBean input) {
                                BiStoreRetGdsHomeVo result = new BiStoreRetGdsHomeVo();
                                result.setCategoryCode(input.getCateCode());
                                result.setCategoryName(input.getCateName());
                                result.setRank(input.getRank());
                                result.setRefund(input.getRefund());
                                result.setRetGdsNum(input.getRetGdsNum());
                                result.setRetGdsRate(input.getRetGdsRate());
                                result.setStatisDate(formatTime(input.getStatisDate()));
                                // 同比计算
                                result.setYoy(getRetGdsYoyMom(input.getRetGdsRate(), input.getLastYearRetGdsNum(),
                                        input.getLastYearSaleVolume()));
                                // 环比计算
                                result.setMom(getRetGdsYoyMom(input.getRetGdsRate(), input.getLastMonRetGdsNum(),
                                        input.getLastMonSaleVolume()));
                                return result;
                            }
                        }));
            }
        }
        return result;
    }

    /**
     * 格式化：20160618 -> ["2016","06","18"]
     */
    private String[] getTheTime(String time) {
        String[] result = null;
        if (StringUtils.isNotBlank(time) && time.length() >= NUM_EIGHT) {
            result = new String[3];
            result[0] = time.substring(NUM_ZERO, NUM_FOUR);
            result[1] = time.substring(NUM_FOUR, NUM_SIX);
            result[2] = time.substring(NUM_SIX, NUM_EIGHT);
        }
        return result;
    }

    /**
     * 格式化：20160618 -> 2016-06-19
     */
    private String formatTime(String time) {
        String result = time;
        String[] times = this.getTheTime(time);
        if (null != times) {
            result = Joiner.on("-").join(Lists.newArrayList(times));
        }
        return result;
    }

    /**
     * 功能描述: <br>
     * 获取三级利润链接信息
     * 
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public Map<String, Object> getThreeProfitUrlInfo() {
        Map<String, Object> result = new HashMap<String, Object>();
        String threeProfitUrl = SCMConfigUtil.getConfig(ConfigConstants.THREE_PROFIT_URL);
        if (StringUtils.isNotBlank(threeProfitUrl)) {
            result.put("threeProfitUrl", threeProfitUrl);
        }
        String threeProfitErrorUrl = SCMConfigUtil.getConfig(ConfigConstants.THREE_PROFIT_ERROR_URL);
        if (StringUtils.isNotBlank(threeProfitErrorUrl)) {
            result.put("threeProfitErrorUrl", threeProfitErrorUrl);
        }
        
        String threeProfitEntranceUrl = SCMConfigUtil.getConfig(ConfigConstants.THREE_PROFIT_ENTRANCE_URL);
        if (StringUtils.isNotBlank(threeProfitEntranceUrl)) {
            result.put(ConfigConstants.THREE_PROFIT_ENTRANCE_URL, threeProfitEntranceUrl);
        }
        return result;
    }

}
